/*
 * 描          述:  <描述>
 * 修  改   人:  PengQingyang
 * 修改时间:  2022年5月1日
 * <修改描述:>
 */
package com.tx.component.sendsms.context;

import java.util.HashMap;
import java.util.Map;

import com.tx.component.communication.model.SendResult;
import com.tx.component.sendsms.model.SendSMSWTChannelEnum;
import com.tx.component.sendsms.model.SendSMSWithTemplateRequest;
import com.tx.component.sendsms.model.SmsTemplate;
import com.tx.component.sendsms.model.SmsTemplateCode;
import com.tx.core.exceptions.util.AssertUtils;
import com.tx.core.util.MessageUtils;

/**
 * 发送短信引擎<br/>
 *    短信会根据模板编号，以及模板寻找到对应的发送渠道
 *    通过对应的发送渠道自动适配对应的短信模板，并调用接口实现短信发送<br/>
 * <功能详细描述>
 * 
 * @author  PengQingyang
 * @version  [版本号, 2022年5月1日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class SendSMSEngineContext extends SendSMSEngineBuilder
        implements SendSMSEngine {
    
    /** 对自身的引用 */
    protected static SendSMSEngine engine;
    
    /**
     * 返回自身唯一引用<br/>
     * @return MRSContext 消息路由服务容器
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     * @version [版本号, 2015年11月12日]
     * @author rain
     */
    public static SendSMSEngine getEngine() {
        if (SendSMSEngineContext.engine != null) {
            return SendSMSEngineContext.engine;
        }
        synchronized (SendSMSEngineContext.class) {
            SendSMSEngineContext.engine = applicationContext.getBean(beanName,
                    SendSMSEngineContext.class);
        }
        
        AssertUtils.notNull(SendSMSEngineContext.engine, "context is null.");
        return SendSMSEngineContext.engine;
    }
    
    /** 是否根据模板验证短信模板参数是否存在 */
    //private boolean validateParameter = false;
    
    /**
     * 发送短信<br/>
     * @param phoneNumbers
     * @param channel
     * @param code
     * @param parameters
     * @return
     */
    @Override
    public SendResult sendWithTemplate(String phoneNumbers,
            SendSMSWTChannelEnum channel, SmsTemplateCode code,
            Map<String, String> parameters) {
        AssertUtils.notEmpty(phoneNumbers, "phoneNumbers is empty.");
        AssertUtils.notNull(channel, "channel is null.");
        AssertUtils.notNull(code, "code is null.");
        
        SmsTemplate smsTemplate = this.smsTemplateService
                .findByCode(code.getCode(), channel);
        if (smsTemplate == null) {
            return SendResult
                    .newFail(MessageUtils.format("渠道:{} 模板:{} 不能存在，请先进行配置后再使用.",
                            new Object[] { channel, code }));
        }
        
        SendResult result = sendWithTemplate(phoneNumbers,
                channel,
                smsTemplate.getTemplateCode(),
                parameters,
                smsTemplate.getSignName());
        return result;
    }
    
    /**
     * 发送短信<br/>
     * @param phoneNumbers
     * @param code
     * @param parameters
     * @return
     */
    @Override
    public SendResult sendWithTemplate(String phoneNumbers,
            SmsTemplateCode code, Map<String, String> parameters) {
        AssertUtils.notEmpty(phoneNumbers, "phoneNumbers is empty.");
        AssertUtils.notNull(code, "code is null.");
        
        SmsTemplate smsTemplate = this.smsTemplateService
                .findFirstByCode(code.getCode());
        if (smsTemplate == null) {
            return SendResult.newFail(MessageUtils
                    .format("模板:{} 不能存在，请先进行配置后再使用.", new Object[] { code }));
        }
        
        SendResult result = sendWithTemplate(phoneNumbers,
                smsTemplate.getChannel(),
                smsTemplate.getTemplateCode(),
                parameters,
                smsTemplate.getSignName());
        return result;
    }
    
    /**
     * @param phoneNumbers
     * @param channel
     * @param templateCode
     * @param parameters
     * @return
     */
    @Override
    public SendResult sendWithTemplate(String phoneNumbers,
            SendSMSWTChannelEnum channel, String templateCode,
            Map<String, String> parameters) {
        AssertUtils.notEmpty(phoneNumbers, "phoneNumbers is empty.");
        AssertUtils.notNull(channel, "channel is null.");
        AssertUtils.notEmpty(templateCode, "templateCode is empty.");
        
        SendSMSWithTemplateRequest request = new SendSMSWithTemplateRequest();
        request.setPhoneNumbers(phoneNumbers);
        request.setChannel(channel);
        request.setTemplateCode(templateCode);
        request.setTemplateParam(
                parameters == null ? new HashMap<>() : parameters);
        
        SendResult result = this.composite.sendWithTemplate(request);
        return result;
    }
    
    /**
     * 
     * @param phoneNumbers
     * @param channel
     * @param templateCode
     * @param parameters
     * @param signName
     * @return
     */
    @Override
    public SendResult sendWithTemplate(String phoneNumbers,
            SendSMSWTChannelEnum channel, String templateCode,
            Map<String, String> parameters, String signName) {
        AssertUtils.notEmpty(phoneNumbers, "phoneNumbers is empty.");
        AssertUtils.notNull(channel, "channel is null.");
        AssertUtils.notEmpty(templateCode, "templateCode is empty.");
        
        SendSMSWithTemplateRequest request = new SendSMSWithTemplateRequest();
        request.setPhoneNumbers(phoneNumbers);
        request.setChannel(channel);
        request.setSignName(signName);
        request.setTemplateCode(templateCode);
        request.setTemplateParam(
                parameters == null ? new HashMap<>() : parameters);
        
        SendResult result = this.composite.sendWithTemplate(request);
        return result;
    }
    
    /**
     * @param request
     * @return
     */
    @Override
    public SendResult sendWithTemplate(SendSMSWithTemplateRequest request) {
        AssertUtils.notNull(request, "request is null.");
        AssertUtils.notEmpty(request.getPhoneNumbers(),
                "request.phoneNumbers is empty.");
        AssertUtils.notNull(request.getChannel(), "request.channel is null.");
        AssertUtils.notEmpty(request.getTemplateCode(),
                "request.templateCode is empty.");
        
        SendResult result = this.composite.sendWithTemplate(request);
        return result;
    }
    
    /**
     * 获取第三方账户类型集合<br/>
     * <功能详细描述>
     * @return [参数说明]
     * 
     * @return List<SmsTemplateCode> [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    @Override
    public Map<String, SmsTemplateCode> getTemplateCodeMap() {
        Map<String, SmsTemplateCode> res = this.smsTemplateService
                .getTemplateCodeMap();
        return res;
    }
    
    /**
     * 获取登陆插件<br/>
     * <功能详细描述>
     * @param code
     * @return [参数说明]
     * 
     * @return LoginPlugin<LoginPluginConfig> [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    @Override
    public SmsTemplateCode getTemplateCode(String code) {
        AssertUtils.notEmpty(code, "code is empty.");
        
        SmsTemplateCode smsTemplateCode = this.smsTemplateService
                .getTemplateCode(code);
        return smsTemplateCode;
    }
    
}
